﻿#pragma once

#include "OCMain/Log.h"
#include "OCGIS/GDALCPP.h"
#include "ogr_spatialref.h"
#include "OCVolume/VolumeD3Writer.h"
#include "OCVolume/VolumeGridData.h"

using namespace OCPP;

void readASC(String fileName)
{
	OCPP_LOG_INFO << fileName << "\n";
	std::ifstream ifs(fileName);
	if (!ifs) return;
	String line;
	for (int i = 0; i < 6; i++)
		getline(ifs, line);
	float minValue = 1e+5;
	float maxValue = -minValue;
	size_t rowCount = 0;
	while (getline(ifs, line))
	{
		if (line.empty())
			break;
		StringVector sv = StringUtil::split(line," ",0,false);
		if (sv.size() == 483)
		{
			for (const auto& v : sv)
			{
				if (v.empty()) continue;
				float f = std::stof(v);
				minValue = std::min(f, minValue);
				maxValue = std::max(f, maxValue);
			}
			rowCount++;
		}
	}
	OCPP_LOG_INFO << "minValue:" << minValue << "\n";
	OCPP_LOG_INFO << "maxValue:" << maxValue << "\n";
	OCPP_LOG_INFO << "rowCount:" << rowCount << "\n";
}

void asc2w3dm()
{
	String dir = "I:\\Project\\2024\\长科院\\长安大学\\洪水侵蚀运行输入输出文件 - 袁家村05.15\\洪水侵蚀运行输入输出文件 - 袁家村\\output";
	dir = StringUtil::UTF8ToANSI(dir);
	StringVector files = FileUtil::findFiles(dir);
	for (const auto& name : files)
	{
		if (FileUtil::getFileExtension(name) != "asc") continue;
		if (!StringUtil::startsWith(name, "h_")) continue;
		readASC(joinPath(dir, name));
	}
}

void asc2w3dm1()
{
	OCPP_LOG_INFO << "asc2w3dm\n";

	String dir = "I:\\Project\\2023\\官山河流域\\2023\\新建文件夹";
	dir = StringUtil::UTF8ToANSI(dir);

	StringVector files = FileUtil::findFiles(dir);

	for (auto name : files)
	{
		if (FileUtil::getFileExtension(name) != "asc") continue;
		name = StringUtil::UTF8ToANSI(name);

		String fileName = joinPath(dir, name);

		std::ifstream ifs(fileName);
		if (!ifs)
		{
			return;
		}

		VolumeGridData volumeGridData;
		volumeGridData.setType(VolumeGridData::Type_Char);
		volumeGridData.addDimension(name);

		int ncols{ 1 }, nrows{ 1 };
		double xllcorner{ 0.0 }, yllcorner{ 0.0 };
		float cellsize{ 0.0 };
		float nodataValue{ 0.0 };

		float minValue = 9999.0, maxValue = -9999.0;
		int validCount = 0;

		String line;
		size_t lineCount = 0;
		for (; getline(ifs, line); lineCount++)
		{
			if (line.empty())continue;
			StringVector sv = StringUtil::split(line);
			if (lineCount == 0)
			{
				ncols = std::stoi(sv[sv.size() - 1]);
			}
			else if (lineCount == 1)
			{
				nrows = std::stof(sv[sv.size() - 1]);
			}
			else if (lineCount == 2)
			{
				xllcorner = std::stod(sv[sv.size() - 1]);
			}
			else if (lineCount == 3)
			{
				yllcorner = std::stod(sv[sv.size() - 1]);
			}
			else if (lineCount == 4)
			{
				cellsize = std::stof(sv[sv.size() - 1]);
			}
			else if (lineCount == 5)
			{
				nodataValue = std::stof(sv[sv.size() - 1]);
			}
			else
			{
				for (int i = 0; i < ncols; i++)
				{
					float value = std::stof(sv[i]);
					if (!Math::floatEqual(nodataValue, value))
					{
						validCount++;
						if (minValue > value) minValue = value;
						if (maxValue < value) maxValue = value;
					}
					else
					{
						value = 0.0f;
					}

					uint8 enc = value * 10;
					volumeGridData._vecChar.push_back(enc);
					volumeGridData._vecFloat.push_back(value);
				}
			}
		}
		OCPP_LOG_INFO << "minValue:" << minValue << "\n";
		OCPP_LOG_INFO << "maxValue:" << maxValue << "\n";

		double west = xllcorner;
		double south = yllcorner;
		double east = west + cellsize * ncols;
		double north = south + cellsize * nrows;

		{
			SRS srs(4546);
			OGRCoordinateTransformation* transform = srs.getTransform(4326);
			transform->Transform(1, &south, &west);
			transform->Transform(1, &north, &east);
		}


		volumeGridData.getExtent().dimX = ncols;
		volumeGridData.getExtent().dimY = nrows;
		volumeGridData.getExtent().dimZ = 1;
		volumeGridData.getExtent().xMin = west;
		volumeGridData.getExtent().yMin = south;
		volumeGridData.getExtent().xMax = east;
		volumeGridData.getExtent().yMax = north;

		StringMap options;

		//VolumeD3Writer writer;
		//writer.setOutputPath(dir);
		//writer.write(volumeGridData, options);

		VolumeJsonWriter writer2;
		writer2.setOutputPath(dir);
		volumeGridData.setType(VolumeGridData::Type_Float);
		writer2.write(volumeGridData, options);

		//Json::Value root;

		//root["startLon"] = west;
		//root["startLat"] = south;
		//root["endLon"] = east;
		//root["endLat"] = north;
		//root["numLon"] = ncols;
		//root["numLat"] = nrows;
		//root["minValue"] = minValue;
		//root["maxValue"] = maxValue;
		//root["validCount"] = validCount;
		//root["nodataValue"] = nodataValue;

		//OCPP_LOG_INFO << ServerUtil::jsonToString(root, " ") << "\n";

		//root["DS"] = data;
		//fileName = joinPath(dir, name + ".json");
		//std::ofstream ofs(fileName);
		//ofs << ServerUtil::jsonToString(root, "");
	}
}